package com.flower.ApiGateway.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.flower.ApiGateway.entity.HttpResponseBean;
import com.flower.ApiGateway.untils.JwtTokenUtil;
import com.flower.ApiGateway.untils.MAPIHttpServletRequestWrapper;
import org.apache.commons.io.IOUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;


@EnableWebMvc
@Configuration
public class JwtFilter implements Filter {

    private Logger logger = Logger.getLogger("JwtFilter");


    private JwtTokenUtil jwtTokenUtil;

    private InputStream is;

    public JwtTokenUtil getJwtTokenUtil() {
        return jwtTokenUtil;
    }

    public void setJwtTokenUtil(JwtTokenUtil jwtTokenUtil) {
        this.jwtTokenUtil = jwtTokenUtil;
    }

    private static final String TOKEN_HEADER = "X-AUTH-TOKEN";
    private static final String HTTP_STATUS_ERROR = "999999";
    private static final String HTTP_TOKEN_MESSAGE_INVALID = "token异常";

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        response.setCharacterEncoding("UTF-8");
        HttpResponseBean responseWsBean = new HttpResponseBean();
        ServletRequest requestWrapper = null;
        if(request instanceof HttpServletRequest) {
            requestWrapper = new MAPIHttpServletRequestWrapper((HttpServletRequest) request);
        }
        //secretKey
        //请求头上的token
        String jsonTokenWeb = request.getHeader(TOKEN_HEADER);
        if(jsonTokenWeb == null) {
            //在从request取一次 用于ajax
            String contentStr = "";
            try {
                is = requestWrapper.getInputStream();
                contentStr = IOUtils.toString(is, "UTF-8");
            } catch (IOException e) {
                e.printStackTrace();
            }
            JSONObject body = JSON.parseObject(contentStr);
            try {
                jsonTokenWeb= body.getString("token");
            }catch (Exception e){
                logger.info("token异常");
                setResponseWsBean(responseWsBean, HTTP_STATUS_ERROR, HTTP_TOKEN_MESSAGE_INVALID);
                response.getWriter().write(JSON.toJSON(responseWsBean).toString());
                return;
            }
        }
        try {
            Boolean validateToken = jwtTokenUtil.validateToken(jsonTokenWeb);
            if(validateToken) {
                filterChain.doFilter(requestWrapper,response);
            }else {
                logger.info("token错误");
                setResponseWsBean(responseWsBean, HTTP_STATUS_ERROR, HTTP_TOKEN_MESSAGE_INVALID);
                response.getWriter().write(JSON.toJSON(responseWsBean).toString());
                return;
            }
        } catch (Exception e) {
            logger.info("token异常");
            setResponseWsBean(responseWsBean, HTTP_STATUS_ERROR, HTTP_TOKEN_MESSAGE_INVALID);
            response.getWriter().write(JSON.toJSON(responseWsBean).toString());
            return;
        }


    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        ServletContext context = config.getServletContext();
        ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
        jwtTokenUtil = ctx.getBean(JwtTokenUtil.class);
    }

    private void setResponseWsBean(HttpResponseBean responseWsBean, String httpStatus , String message){
        responseWsBean.setHttpStatus(httpStatus);
        responseWsBean.setMessage(message);
    }

}